/* 
 * HibernateValidatorRuleImpl.java
 * 
 * Data de criação: 10/08/2010
 * 
 * O2SOLUTIONS - SOLUÇÕES EM TECNOLOGIA DA INFORMAÇÃO. 
 *
 */
package br.com.o2solutions.core.business.rule.impl;

import java.util.ArrayList;

import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;

import br.com.o2solutions.core.exception.BusinessException;
import br.com.o2solutions.core.exception.enumerator.ExceptionScope;
import br.com.o2solutions.core.service.rule.Rule;
import br.com.o2solutions.util.assertion.Assert;

/**
 * Classe responsável por implementar a validação utilizando o hibernate
 * validator para as classes anotadas para tal verificação.
 * 
 * @author osvaldeir
 * @since 10/08/2010
 * 
 */
public abstract class HibernateValidatorRule<T> implements Rule<T> {

	private ClassValidator<T> validator;

	/**
	 * Realiza a validação da entidade anotada com as anotações hibernate
	 * validator.
	 */
	@Override
	public void check(T entity) throws BusinessException {
		initializeValidator(entity);
		InvalidValue[] invalidValues = validator.getInvalidValues(entity);
		if (invalidValues != null) {
			ArrayList<BusinessException> exceptions = new ArrayList<BusinessException>();
			BusinessException toLaunch = new BusinessException(exceptions);
			for (InvalidValue invalidValue : invalidValues) {
				BusinessException validate = new BusinessException(
						invalidValue.getMessage(), invalidValue.getMessage(),
						ExceptionScope.BUSINESS_VALIDATION,
						invalidValue.getPropertyName(),
						invalidValue.getPropertyPath());
				exceptions.add(validate);
			}
			throw toLaunch;
		}
	}

	/*
	 * Inicializa o validador para a entidade.
	 * 
	 * @param entity Entidade a ser verificada.
	 */
	@SuppressWarnings({ "unchecked" })
	private void initializeValidator(T entity) {
		Assert.notNull(entity,
				"A entidade a ser validada via anotação não pode ser nula");
		validator = new ClassValidator<T>((Class<T>) entity.getClass());
	}

}
